package com.boilermaker.captcha.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.boilermaker.captcha.model.CaptchaProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping("/captcha")
public class CaptchaController {

    @Autowired
    private CaptchaProperties captchaProperties;

    private static final long VALID_MILLIS_TIME = 60 * 1000;

    @RequestMapping("/getCaptcha")
    // 这里的response和session都是输出型参数
    // 因为验证码是和某一个用户绑定的，应当放到session中
    public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException {
        // 手动指定响应格式，以免浏览器默认解析错误
        response.setContentType("image/jpeg");
        // 定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(
                captchaProperties.getWidth(), captchaProperties.getHeight());
        // 写出到流
        lineCaptcha.write(response.getOutputStream());
        String code = lineCaptcha.getCode();
        session.setAttribute(captchaProperties.getSession().getKey(), code);
        session.setAttribute(captchaProperties.getSession().getDate(), new Date());
    }

    @RequestMapping("/check")
    // 接收用户传入的验证码作为参数
    public boolean checkCaptcha(String captcha, HttpSession session) {
        // 若为空值则无需进行进一步判断
        if (!StringUtils.hasLength(captcha)) return false;

        String val = (String)session.getAttribute(captchaProperties.getSession().getKey());
        Date date = (Date)session.getAttribute(captchaProperties.getSession().getDate());

        // 值相同并且未超时
        return captcha.equalsIgnoreCase(val) &&
                System.currentTimeMillis() - date.getTime() <= VALID_MILLIS_TIME;
    }
}
